﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;

using ProjectBase.Core;
using ProjectBase.Tools.Publishing.Handlers.ExceptionHandler;
using $safeprojectname$.Infrastructure.Exceptions;

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace $safeprojectname$.Publishing.Handlers
{
    [TestClass]
    public class ExceptionStringBuilderTest : TestBase
    {
        [TestMethod]
        public void SerializationInfo_Passed()
        {
            var builder = new ExceptionStringBuilder();

            var context = new StreamingContext();
            var info = new SerializationInfo(GetType(), new FormatterConverter());

            info.AddValue("ClassName", string.Empty);
            info.AddValue("Message", string.Empty);
            info.AddValue("InnerException", new ArgumentException());
            info.AddValue("HelpURL", string.Empty);
            info.AddValue("StackTraceString", string.Empty);
            info.AddValue("RemoteStackTraceString", string.Empty);
            info.AddValue("RemoteStackIndex", 0);
            info.AddValue("ExceptionMethod", string.Empty);
            info.AddValue("HResult", 1);
            info.AddValue("Source", string.Empty);

            var exception = new ComplexException(info, context);

            var result = builder.Build(exception);

            Assert.IsTrue(result.IsNotEmpty());
            Assert.IsTrue(result.Contains("test2"), result);
            Assert.IsTrue(result.Contains("testvalue1"));
        }

        [TestMethod]
        public void ComplexException_Passed()
        {
            var builder = new ExceptionStringBuilder();

            var exception = new ComplexException("Message");

            var result = builder.Build(exception);

            Assert.IsTrue(result.IsNotEmpty());
            Assert.IsTrue(result.Contains("test2"));
            Assert.IsTrue(result.Contains("testvalue1"));
        }
        [TestMethod]
        public void ComplexExceptionWithoutData_Passed()
        {
            var builder = new ExceptionStringBuilder();
            var exception = new ComplexException();


            var result = builder.Build(exception);

            Assert.IsTrue(result.IsNotEmpty());
            Assert.IsFalse(result.Contains("test2"));
            Assert.IsFalse(result.Contains("testvalue1"));
        }

        [TestMethod]
        public void ExceptionWithAdditionalData_Passed()
        {
            var builder = new ExceptionStringBuilder();
            var exception = new ComplexException("Message");

            var additional = new NameValueCollection();
            additional.Add("key1", "value1");
            additional.Add("key2", "value2");
            var result = builder.Build(exception, additional);

            Assert.IsTrue(result.IsNotEmpty());
            Assert.IsTrue(result.Contains("key1"));
            Assert.IsTrue(result.Contains("value2"));
        }

        [TestMethod]
        public void MathException_Passed()
        {
            Exception exception = null;
            try
            {
                int i = 1;
                int j = 0;
                var x = i / j;
            }
            catch (Exception ex)
            {
                exception = ex;
            }
            var builder = new ExceptionStringBuilder();

            var result = builder.Build(exception);

            Assert.IsTrue(result.IsNotEmpty());
        }

        #region Init

        // You can use the following additional attributes as you write your tests:

        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }

        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }

        [TestInitialize]
        public override void MyTestInitialize()
        {
            base.MyTestInitialize(); // Use TestInitialize to run code before running each test
        }

        [TestCleanup]
        public override void MyTestCleanup()
        {
            base.MyTestCleanup(); // Use TestCleanup to run code after each test has run
        }
        #endregion Init
    }
}
